package com.lu.manage.core.utils;

import com.lu.manage.core.common.constant.SystemConstant;
import com.lu.manage.modular.system.model.Dict;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
 * @program sKnowledge_Blog
 * @description: 反射工具类
 * @author: zhanglu
 * @create: 2019-07-06 23:50:00
 */
public class ReflexUtils {

    /**
     * 配置主入口
     * @param clazz
     * @param dictList
     * @param codes
     */
    public static void configure(Class clazz, Object obj, List<Dict> dictList, List<String> codes){
        Method[] methods = clazz.getDeclaredMethods();
        ReflexUtils.handle(obj, dictList, methods, codes);
    }

    /**
     * 执行配置
     * @param obj
     * @param dictList
     * @param methods
     * @param codes
     */
    public static void handle(Object obj, List<Dict> dictList, Method[] methods, List<String> codes){
        final String[] msg = {""};
        dictList.stream().forEach(o -> {
            try {
                invokeMethod(obj, methods, o);
            } catch (Exception e) {
                msg[0] += e;
            }
        });
        if(ToolUtil.isNotEmpty(codes)){
            //默认的加载
            codes.stream().forEach(code -> {
                dictList.stream()
                    .filter(o -> o.getDictKey().equals(code))
                    .forEach(o -> {
                        try {
                            invokeMethod(obj, methods, o);
                        } catch (Exception e) {
                            msg[0] += e;
                        }
                    });
            });
        }

    }

    public static void invokeMethod(Object obj, Method[] methods, Dict o) throws InvocationTargetException, IllegalAccessException {
        String method = "set" + StringUtil.acronymToUpperCase(o.getDictKey());
        if(method.indexOf(SystemConstant.ARRAY_DIVISION) > 0){
            method = method.substring(0, method.indexOf(SystemConstant.ARRAY_DIVISION));
        }
        for(Method m : methods){
            if(m.getName().equals(method)){
                m.invoke(obj, o.getDictValue());
                return;
            }
        }
    }

    public static void invokeBlogAboutMethod(Map<String, Object> map, Class obj, Method[] methods, Dict o) throws InvocationTargetException, IllegalAccessException, InstantiationException {
        String method = "set" + StringUtil.acronymToUpperCase(o.getDictKey());
        for(Method m : methods){
            if(method.contains(m.getName())){
                String index = method.replace(m.getName(), "");
                if(!map.containsKey(index)){
                    map.put(index, obj.newInstance());
                }
                m.invoke(map.get(index), o.getDictValue());
                return;
            }
        }
    }

    public static void handle(Object obj, List<Dict> dictList, Field[] fields, List<String> codes){
        dictList.stream().forEach(o -> {
            setField(obj, fields, o);
        });
        codes.stream().forEach(code -> {
            dictList.stream()
                    .filter(o -> o.getDictKey().equals(code))
                    .forEach(o -> {
                        setField(obj, fields, o);
                    });
        });
    }

    public static void setField(Object obj, Field[] fields, Dict o){
        for(Field f : fields){
            if(f.getName().equals(o.getDictKey())){
                try {
                    f.setAccessible(true);
                    f.set(obj, o.getDictValue());
                    return;
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
